/**
 *  Copyright 2011 Marco Berri - marcoberri@gmail.com
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and limitations under the License.
 **/
package com.mbfasttrack.service;

import com.mbfasttrack.model.Group;
import com.mbfasttrack.model.Track;
import com.mbfasttrack.model.User;
import com.mbfasttrack.utils.DateTimeUtil;
import com.mbfasttrack.utils.StringUtil;
import java.util.List;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author Marco Berri marcoberri@gmail.com http://tecnicume.blogspot.com
 */
@Service("GroupService")
@Transactional
public class GroupService extends Base {

    /**
     * 
     * @param group 
     * @param username
     * @return
     */
    public Group add(Group group, String username) {
        group.setUser(userRepository.findOneByUsername(username));
        group.addUserAdminLink(group.getUser());
        group.addUserLink(group.getUser());

        return this.add(group);
    }

    /**
     * 
     * @param group
     * @param username
     * @return
     */
    public Group addUser(Group group, String username) {

        if (group.getId() == null) {
            return null;
        }


        //verifico che non sia già stato aggiunto
        for (User u : group.getUserAdminLink()) {

            if (!u.getUsername().equalsIgnoreCase(username)) {
                continue;
            }

            return group;

        }

        group.addUserAdminLink(userRepository.findOneByUsername(username));
        return this.save(group);

    }

    /**
     * 
     * @param group
     * @param username
     * @return
     */
    public Group addUserAdmin(Group group, String username) {
        if (group.getId() == null) {
            return null;
        }

        //verifico che non sia già stato aggiunto
        for (User u : group.getUserLink()) {

            if (!u.getUsername().equalsIgnoreCase(username)) {
                continue;
            }

            return group;

        }

        group.addUserLink(userRepository.findOneByUsername(username));
        return this.save(group);
    }

    public Group add(Group group) {

        String slug = StringUtil.normalize(group.getName());

        if (groupRepository.findOneBySlug(slug) != null) {
            slug += "-" + DateTimeUtil.getNowWithFormat("yyyy-MM-dd");
        }

        group.setSlug(slug);

        //parso i tag
        if (group.getTags() != null && !"".equalsIgnoreCase(group.getTags().trim())) {
            String[] split_tags = group.getTags().split(",");
            for (String tag_name : split_tags) {
                group.addTagLink(tagService.add(tag_name, 0));
            }
        }

        return this.save(group);
    }

    /**
     * 
     * @param username
     * @return
     */
    public List<Group> findAdminByUsername(String username) {

        return findAdminByUserId(userService.userRepository.findOneByUsername(username).getId());
    }

    /**
     * 
     * @param id
     * @return
     */
    public List<Group> findAdminByUserId(String id) {

        Query q = new Query(
                Criteria.where("user.$id").is(new ObjectId(id))).limit(10);
        System.err.print("Query:" + q);

        return mongoTemplate.find(q, Group.class);

    }

    /**
     * 
     * @param username
     * @return
     */
    public List<Group> findByUsername(String username) {
        User u = userService.userRepository.findOneByUsername(username);
        if (u == null) {
            return null;
        }

        log.debug("u : " + u.getId());

        return findByUserId(u.getId());
    }

    /**
     * 
     * @param id
     * @return
     */
    public List<Group> findByUserId(String id) {

        Query q = new Query(
                Criteria.where("userAdminLink.$id").in(new ObjectId(id)).orOperator(Criteria.where("userLink.$id").in(new ObjectId(id))));
        log.debug("Query:" + q.getQueryObject());

        return mongoTemplate.find(q, Group.class);

    }

    /**
     * 
     * @param group 
     * @return
     */
    public Group save(Group group) {
        return groupRepository.save(group);
    }

    /**
     * 
     * @param group
     * @param track
     * @return
     */
    public Group addTrack(Group group, Track track) {
        if (group.getId() == null) {
            return null;
        }
        group.addTrackLink(track);
        return this.save(group);
    }

    /**
     * 
     * @param groupslug
     * @param trackslug
     * @return
     */
    public Group addTrack(String groupslug, String trackslug) {

        Group g = groupRepository.findOneBySlug(groupslug);

        if (g == null) {
            return g;
        }

        Track t = trackService.trackRepository.findOneBySlug(trackslug);

        if (t == null) {
            return null;
        }


        //verifico che non sia già stato aggiunto
        for (Track tc : g.getTrackLink()) {

            if (tc.getId() == null ? t.getId() != null : !tc.getId().equals(t.getId())) {
                continue;
            }

            return g;

        }

        g.addTrackLink(t);
        return this.save(g);
    }
}
